<template>
  <div class="upload_contant">
    <!-- 文件选择 -->
    <Upload
      ref="Upload"
      :multiple="useModel == 'new'"
      type="drag"
      paste
      action="//jsonplaceholder.typicode.com/posts/"
      :before-upload="getUploadList"
      :accept="enable_type"
      :format="['pdf', 'doc', 'docx']"
    >
      <div style="padding: 20px 0">
        <Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
        <p>点击或拖动文件上传</p>
        <p>编辑模式下 上传的文件会覆盖原文件</p>
      </div>
    </Upload>
    <Button @click="clearlist" shape="circle" long style="margin: 10px 0"
      >清空列表</Button
    >
    <!-- 展示已经选择的文件 -->
    <List header="已经选择的文件:" border size="small">
      <ListItem v-for="(item, i) in uploadList" :key="i">{{
        item.name
      }}</ListItem>
    </List>
    <!-- 提交文章区域 -->
    <div class="demo-carousel">
      <div style="margin-top: 20px">
        <Form :model="formTop" label-position="left">
          <FormItem v-if="useModel != 'new'" label="文件名称">
            <Input v-model="formTop.title"></Input>
          </FormItem>
          <FormItem label="文件说明">
            <Input
              autosize
              v-model="formTop.explain"
              type="textarea"
              placeholder="Enter something..."
            />
          </FormItem>
          <FormItem label="谁可以查看此文件">
            <Select style="width: auto" v-model="formTop.permission">
              <Option
                v-for="item in Checkpermissions"
                :value="item.value"
                :key="item.value"
                >{{ item.label }}</Option
              >
            </Select>
          </FormItem>

          <FormItem label="请选择文件夹">
            <Input v-model="formTop.dir" readonly placeholder=""></Input>
          </FormItem>
        </Form>
        <!-- 选择文件夹 -->
        <Tree
          :data="datadir"
          expand-node
          :render="renderContent"
          class="demo-tree-render"
        >
        </Tree>
        <!-- 提交按钮 -->
        <Button @click="submit" type="success" long>开始上传</Button>
      </div>
    </div>
  </div>
</template>

<script>
import { resolveComponent } from 'vue'
import putBuffer from '@/api/API_Uploading_Directory_Tree'
import {
  nodeType_children_node,
  nodeType_root_node,
  nodeType_pdf,
  nodeType_article
} from '@/mylibs/define'
import { getUuid, getNowTime, find_dirNode } from '@/mylibs/functions'
// render
import { renderContent } from '@/mylibs/node_render'
import eventbus from '@/eventBus/eventbus'

export default {
  props: {
    useModel: {
      default: 'new',
      required: true,
      type: String
    },
    PATH_document_file: { required: true, type: String },
    PATH_Directory_tree: { required: true, type: String }
  },

  data() {
    return {
      needEdit_nodeData: null,
      enable_type: '.pdf,.doc',
      datadir: [],
      chooseDir_node: null,
      uploadList: [],
      loadingStatus: true,
      // 文章权限
      Checkpermissions: [
        {
          value: '仅自己',
          label: '仅自己'
        },
        {
          value: '所有人',
          label: '所有人'
        }
      ],
      formTop: {
        title: '',
        dir: '',
        permission: '仅自己',
        // 文章说明信息
        explain: ''
      },
      buttonProps: {
        type: 'default',
        size: 'small'
      },

      // 文章节点样式
      art_render: (h, { root, node, data }) => {
        return h(
          'span',
          {
            style: {
              display: 'inline-block',
              width: '100%'
            }
          },
          [
            h('span', [
              h(resolveComponent('Icon'), {
                type: 'ios-paper-outline',
                style: {
                  marginRight: '8px'
                }
              }),
              h('span', data.title)
            ])
          ]
        )
      },

      // pdf节点样式
      pdf_render: (h, { root, node, data }) => {
        return h(
          'span',
          {
            style: {
              display: 'inline-block',
              width: '100%'
            }
          },
          [
            h('span', [
              h(resolveComponent('Icon'), {
                type: 'ios-leaf-outline',
                style: {
                  marginRight: '8px'
                }
              }),
              h('span', data.title)
            ])
          ]
        )
      },

      renderContent
    }
  },

  methods: {
    // 消息提示
    info(desc) {
      this.$Notice.info({
        title: '注意!',
        desc
      })
    },

    // 获取目录树数据
    async getDirTreeData(fun_back) {
      var { res, ok, err } = await putBuffer('get', this.PATH_Directory_tree)

      if (ok) {
        if (res) {
          if (Array.isArray(res)) {
            console.log(1)
            this.datadir = res
            // 设置根文章节点样式
            this.Recursive_directory_tree(this.datadir)
            // 回调
            if (fun_back) {
              fun_back({ res, ok, err })
            }
          } else {
            this.$Notice.info('数据非数组')
          }
        }
      } else {
        this.$Notice.error({ desc: '获取目录树数据失败:' + err })
      }
    },

    // 获取要上传的文件
    getUploadList(upload) {
      if (this.useModel == 'edit') {
        this.uploadList.splice(0)

        this.formTop.title = upload.name
      }

      this.uploadList.push(upload)
      return false
    },

    // 提交数据
    async submit() {
      // 条件判断
      if (this.chooseDir_node == null) return this.info('请选择文件夹')
      if (this.formTop.permission.length == 0) return this.info('请选择权限')

      // 新建上传
      if (this.useModel == 'new') {
        // 循环文件列表
        for (var index = 0; index < this.uploadList.length; index++) {
          var file = this.uploadList[index]

          var id = getUuid()
          var bucket_filepath = this.PATH_document_file + id + '/' + file.name

          var { res, ok, err } = await putBuffer(
            'put',
            bucket_filepath,
            file,
            true
          )

          if (ok) {
            this.$Notice.success({ desc: '文件单独保存成功' })
            // 回调函数,注意执行顺序
            // 准备文件节点数据
            var render = this.renderContent
            var type = file.type.split('/')[1]
            if (type == nodeType_pdf) {
              var render = this.pdf_render
            }

            var node = {
              title: file.name,
              mynodeKey: getUuid(),
              // type :"application/pdf"
              node_type: type,
              father_nodeKey: this.chooseDir_node.mynodeKey,
              render,
              upload: {
                bucket_filepath,
                explain: this.formTop.explain,
                release_time: getNowTime(),
                update_time: '',
                permission: this.formTop.permission
              }
            }

            // 把数据添加到父节点 children 属性上
            var children = this.chooseDir_node.children || []
            children.push(node)
            this.chooseDir_node.children = children

            // 把目录树数据data保存到阿里云oss
            var { ok, err } = await putBuffer(
              'put',
              this.PATH_Directory_tree,
              this.datadir
            )

            if (ok) {
              this.$Notice.success({ desc: '目录树保存成功' })
              // 最后一个
              if (index == this.uploadList.length - 1) {
                // 后续处理
                this.uploadList = []
                this.formTop.dir = ''
                this.formTop.explain = ''
                this.formTop.permission = ''
                this.chooseDir_node = null
              }
            } else {
              this.$Notice.error({ desc: '保存目录数据失败:' + err })
            }
          } else {
            this.$Notice.error({ desc: '提交文件数据失败:' + err })
          }
        }
      }

      // 编辑信息
      else {
        var title, bucket_filepath
        // 是否重命名

        if (this.formTop.title == this.needEdit_nodeData.title) {
          var is_rename = false
          title = this.needEdit_nodeData.title
          bucket_filepath = this.needEdit_nodeData.upload.bucket_filepath
        } else {
          var is_rename = true
          title = this.formTop.title
          bucket_filepath = this.PATH_document_file + getUuid() + '/' + title

          // oss重命名文档
          var { ok, err } = await putBuffer('rename', {
            oldname: this.needEdit_nodeData.upload.bucket_filepath,
            newname: bucket_filepath
          })

          if (ok) {
            this.$Notice.success({ desc: '重命名文档成功' })
          } else {
            this.$Notice.error({ desc: 'oss重命名文档失败:' + err })
          }
        }

        if (ok || !is_rename) {
          var node_type = this.needEdit_nodeData.node_type
          // 如果从新上传了文件
          if (this.uploadList.length != 0) {
            putBuffer('put', bucket_filepath, this.uploadList[0], true).then(
              ({ res, ok, err }) => {
                if (!ok) {
                  this.$Notice.error({ desc: '覆盖原文件失败:' + err })
                  // 覆盖失败可以继续
                } else {
                  this.$Notice.success({ desc: '覆盖原文档成功' })
                  this.uploadList.splice(0)
                }
              }
            )

            node_type = this.uploadList[0].type.split('/')[1]
          }

          // 准备文件节点数据
          var node = {
            title,
            mynodeKey: getUuid(),
            node_type,
            father_nodeKey: this.chooseDir_node.mynodeKey,
            render: this.needEdit_nodeData.render,
            upload: {
              bucket_filepath,
              explain: this.formTop.explain,
              release_time: getNowTime(),
              permission: this.formTop.permission
            }
          }

          // 把数据添加到父节点 children 属性上
          var children = this.chooseDir_node.children || []
          children.push(node)
          this.chooseDir_node.children = children

          // 把目录树数据data保存到阿里云oss
          putBuffer('put', this.PATH_Directory_tree, this.datadir).then(
            ({ res, ok, err }) => {
              if (!ok) {
                this.$Notice.error({
                  desc:
                    '目录树数据保存到阿里云oss失败,该节点可能已经失效:' + err
                })
              } else {
                this.$Notice.success({ desc: '目录树保存成功' })
                this.uploadList.splice(0)
                this.needEdit_nodeData = null
                this.formTop.title = ''
                this.formTop.explain = ''
                this.formTop.permission = ''
              }
            }
          )
        }
      }
    },

    //递归目录树数据
    Recursive_directory_tree(dirData) {
      for (let index = 0; index < dirData.length; index++) {
        var element = dirData[index]
        // 设置根文章节点样式
        if (element.node_type && element.node_type == nodeType_article) {
          element['render'] = this.art_render
        }
        // pdf
        if (element.node_type && element.node_type == nodeType_pdf) {
          element['render'] = this.pdf_render
        }
        // 文件夹样式
        if (
          element.node_type &&
          (element.node_type == nodeType_root_node ||
            element.node_type == nodeType_children_node)
        ) {
          element['render'] = (h, { root, node, data }) => {
            return h(
              'span',
              {
                style: {
                  display: 'inline-block',
                  width: '100%'
                }
              },
              [
                h('span', [
                  h(resolveComponent('Icon'), {
                    type: 'md-folder',
                    style: {
                      marginRight: '8px'
                    }
                  }),
                  h('span', data.title)
                ]),
                h(
                  'span',
                  {
                    style: {
                      display: 'inline-block',
                      float: 'right',
                      marginRight: '32px'
                    }
                  },
                  [
                    h(resolveComponent('Button'), {
                      ...this.buttonProps,
                      icon: 'ios-add',
                      style: {
                        marginRight: '8px'
                      },
                      onClick: (e) => {
                        this.chooseDir(data, e)
                      }
                    })
                  ]
                )
              ]
            )
          }
        }

        if (element.children && element.children.length != 0) {
          this.Recursive_directory_tree(element.children)
        }
      }
    },

    // 选择文件夹
    chooseDir(data, e) {
      this.chooseDir_node = data
      this.formTop.dir = data.title
      if (e) e.stopPropagation()
    },

    clearlist() {
      this.$refs.Upload.clearFiles()
      this.uploadList = []
    }
  },

  created() {
    console.log(this.useModel)

    if (this.useModel === 'edit') {
      // 需要编辑文档信息
      // eventBus '优先级(先执行的)'比 created() activated() 要高
      eventbus.on('need_edit_document', (doc_node) => {
        // 编辑之前目录树数据应该保持最新,编辑过程中不要再更新数据,
        // 获取目录树数据
        this.getDirTreeData(({ res, ok, err }) => {
          if (ok) {
            console.log(2)
            this.needEdit_nodeData = doc_node
            this.formTop.title = this.needEdit_nodeData.title
            this.formTop.explain = doc_node.upload.explain
            this.formTop.permission = doc_node.upload.permission

            // 找到节点
            var fatherDir = find_dirNode(
              this.datadir,
              this.needEdit_nodeData.father_nodeKey
            )

            if (fatherDir) {
              // 删除该文章节点在 当前目录树中的位置 提交时再添加 达到从新选择文件夹的效果 ,如果用户不进行提交操作,oss的目录树数据并没有改变
              var children = fatherDir.children || []
              var newlist = []

              newlist = children.filter((item) => {
                return item.mynodeKey != doc_node.mynodeKey
              })

              fatherDir.children = newlist

              this.chooseDir(fatherDir)
            } else {
              this.$Notice.error({ desc: '寻找父节点失败' })
            }
          }
        })
      })
    }
  },

  activated() {
    // this.getDirTreeData()
    // 编辑模式 在此处不要直接更新目录树
    // eventbus.on('need_edit_document', (doc_node)函数 与 activated() 函数先后顺序问题:
    // 先need_edit_document,才activated, 导致this.$set(fatherDir, 'children', children)更改目录树之后还没有保存数据就被更新了
    console.log('upload组件激活:' + this.useModel)

    if (this.useModel == 'new') {
      this.getDirTreeData()
    }

    if (this.useModel === 'edit') {
      eventbus.emit('ev_upload_active')
    }
  }
}
</script>

<style scoped>
.margin {
  margin: 10px 10px;
}

.padding {
  padding: 10px 10px;
}
.upload_contant * {
  margin: 10px 10px;
}
</style>
